package n92_任务调度线程池;

import lombok.extern.slf4j.Slf4j;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static utils.Sleeper.sleep;

/**
 * @author fu
 * @date 2022-04-02 22:17
 * 概要：
 * ---------------------------------------------------------------
 * |                                                              |
 * |           ScheduledThreadPoolExecutor 代替 Timer       |
 * |                                                             |
 * |=============================================================
 */
@Slf4j(topic = "c.T3")
public class T2_ScheduledThreadPoolExecutor_调度功能线程池 {


    public static void main(String[] args) {

        log.debug("------------ main()方法开始 -------------");

//        _test_newScheduledThreadPool_根据核心数_决定串行并行();
//        _test_newScheduledThreadPool_前面异常_不影响后面();
//        _test_newScheduledThreadPool_循环执行_固定开始时间_间隔时长();
        _test_scheduleWithFixedDelay_固定结束后_延迟时长();

    }

    /**
     * Executors工具的 调度功能线程池 根据核心数 和 任务数 决定是并行/串行 运行
     *  前面不会影响后面
     */
    private static void _test_newScheduledThreadPool_根据核心数_决定串行并行() {
        // 带有 调度功能的 线程池
        final ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
//        final ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);

        pool.schedule(()->{
            log.debug("task1");
            sleep(2);
        }, 1, TimeUnit.SECONDS);


        pool.schedule(()->{
            log.debug("task2");
        }, 1, TimeUnit.SECONDS);
    }
    /**
     * Executors工具的 调度功能线程池 前面异常 不会影响 后面
     */
    private static void _test_newScheduledThreadPool_前面异常_不影响后面() {
        // 带有 调度功能的 线程池
//        final ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
//        final ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        final ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();

        pool.schedule(()->{
            log.debug("task1");
            sleep(2);
            int i = 1/0;
            log.debug("task1--结束 结果={}",i);
        }, 1, TimeUnit.SECONDS);


        pool.schedule(()->{
            log.debug("task2");
        }, 1, TimeUnit.SECONDS);
    }

    /**
     * Executors工具的 调度功能线程池 循环执行 【如果有异常 将停止本次循环】
     */
    private static void _test_newScheduledThreadPool_循环执行_固定开始时间_间隔时长() {
        // 带有 调度功能的 线程池
//        final ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
        final ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();

        log.debug("--- 开始 ---");
        // 参数：任务对象 ， 延时时间， 执行的间隔， 单位
        pool.scheduleAtFixedRate(()->{
            log.debug("running......");
            /*----------------------------------------------
             |                                             |
             |  间隔时间 小于 程序过程时间时 以过程时间为准     |
             |                                            |
             ---------------------------------------------*/
            sleep(4);
            log.debug("......end");
//            int i = 1/0;
//            log.debug("task1--结束 结果={}",i);
        }, 3, 1, TimeUnit.SECONDS );

    }

    /**
     * Executors工具的 调度功能线程池
     *  delay ：从上次任务结束的时间开始算 -> 然后等待间隔时间
     */
    private static void _test_scheduleWithFixedDelay_固定结束后_延迟时长(){

//        final ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        final ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
        log.debug("--- 开始 ---");

        final Random RDM = new Random();
        pool.scheduleWithFixedDelay(()->{
            try {
                final int rdmInt = RDM.nextInt(2);

                log.debug("running......{}",rdmInt);
            /*------------------------------------------
             |                                         |
             |  程序间隔时间 是 [运行时间+循环时间]        |
             |                                        |
             -----------------------------------------*/
                sleep(2);


                int i = 1/rdmInt;
                log.debug("task1--结束 结果={}",i);
            } catch (Exception e) {
                e.printStackTrace();
            }

        },3,1, TimeUnit.SECONDS);
    }


}
